package cn.edu.sjtu.stap.util;

import java.util.*;

import org.aspectj.asm.IProgramElement;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ASTNode;

/**
 * Map of ASM and AST elements. This is for the advice weaving in the CFG
 * building process. We can get the weaving info through ASM, and the map is
 * used to reflect that on the AST.
 * 
 * The following modification is done on:
 * 
 * org.aspectj.ajdt.core\src\org\aspectj\ajdt\internal\core\builder\AsmHierarchyBuilder.java
 * (Line list: [426, 780, 948] )
 * 
 * @author William
 * 
 */
public class AstAsmMap {
    private static final AstAsmMap mapping = new AstAsmMap();

    private HashMap<IProgramElement, ASTNode> asmToAst = new HashMap<IProgramElement, ASTNode>();

    private HashMap<ASTNode, IProgramElement> astToAsm = new HashMap<ASTNode, IProgramElement>();

    public AstAsmMap() {
        // Empty.
    }

    public static AstAsmMap getInstance() {
        return mapping;
    }

    public void clear() {
        asmToAst.clear();
        astToAsm.clear();
    }

    public void addMapping(IProgramElement pe, ASTNode astNode) {
        if (null == pe || null == astNode) {
            throw new NullPointerException("The mapping between AST and ASM cannot be null!");
        }

        asmToAst.put(pe, astNode);
        astToAsm.put(astNode, pe);
    }

    public Iterator<IProgramElement> asmIterator() {
        return asmToAst.keySet().iterator();
    }

    public Iterator<ASTNode> astIterator() {
        return astToAsm.keySet().iterator();
    }

    public ASTNode get(IProgramElement pe) {
        return asmToAst.get(pe);
    }

    public IProgramElement get(ASTNode astNode) {
        return astToAsm.get(astNode);
    }
}
